package com.ruoyi.basebill.task;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qimencloud.api.DefaultQimenCloudClient;
import com.qimencloud.api.scene5uc0mzv618.request.WdtStockoutCollectQueryRequest;
import com.qimencloud.api.scene5uc0mzv618.response.WdtStockoutCollectQueryResponse;
import com.ruoyi.basebill.domain.OmsReceiptbill;
import com.ruoyi.basebill.domain.OmsReceiptbillentry;
import com.ruoyi.basebill.domain.QMBillConfig;
import com.ruoyi.basebill.service.impl.OmsReceiptbillServiceImpl;
import com.ruoyi.basebill.task.util.OmsTaskUtil;
import com.ruoyi.basedata.domain.*;
import com.ruoyi.basedata.service.impl.*;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
import com.taobao.api.ApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component("OmsGetWdtSaleIssueBillTask")
public class OmsGetWdtSaleIssueBillTask {

    //注入自己
    @Autowired
    private OmsGetWdtSaleIssueBillTask getWdtSaleIssueBillTask;

    @Autowired
    private ObjectMapper objectMapper;
    //系统参数服务层接口
    @Autowired
    private ISysConfigService sysConfigService;

    //店铺服务层接口
    @Autowired
    private BdShopServiceImpl shopService;

    //物料服务层接口
    @Autowired
    private BdMaterialServiceImpl materialService;

    //收货确认服务层接口
    @Autowired
    private OmsReceiptbillServiceImpl receiptbillService;

    //仓库服务层接口
    @Autowired
    private BdWarehouseServiceImpl warehouseService;

    //结算组织服务层接口
    @Autowired
    private OmsOrgunitServiceImpl orgunitService;

    //客户服务层接口
    @Autowired
    private BdCustomerServiceImpl customerService;

    @Transactional(rollbackFor = Exception.class)
    public void getBillData() throws JsonProcessingException, ApiException, ParseException {
        SysConfig qmSaleConfig = sysConfigService.selectConfigByConfigKey("QM_sale_config");
        QMBillConfig qmBillConfig = new QMBillConfig();
        qmBillConfig.setStartTime(LocalDate.now().minusDays(1));
        qmBillConfig.setEndTime(LocalDate.now().minusDays(1));
        qmBillConfig.setShopNo("");
        qmBillConfig.setPageNo(1);
        qmBillConfig.setPageSize(100);
        String s = objectMapper.writeValueAsString(qmBillConfig);
        qmSaleConfig.setConfigValue(s);
        sysConfigService.updateConfig(qmSaleConfig);
        getWdtSaleIssueBillTask.getWdtSaleBill(qmBillConfig);
    }

    @Transactional(rollbackFor = Exception.class)
    public void getBillData(String pageNo,String pageSize,String startDate,String endDate,String shopNo) throws JsonProcessingException, ApiException, ParseException {
        SysConfig qmSaleConfig = sysConfigService.selectConfigByConfigKey("QM_sale_config");
        QMBillConfig qmBillConfig = new QMBillConfig();
        OmsTaskUtil.formatWdtData(pageNo, pageSize, startDate, endDate, shopNo,qmBillConfig);
        String s = objectMapper.writeValueAsString(qmBillConfig);
        qmSaleConfig.setConfigValue(s);
        sysConfigService.updateConfig(qmSaleConfig);
        getWdtSaleIssueBillTask.getWdtSaleBillAllNumber(qmBillConfig);
    }

    /**
     * 格式化前端传入的数据
     * @param pageNo
     * @param pageSize
     * @param startDate
     * @param endDate
     * @param shopNo
     */

    /**
     * 获取符合条件单据总数
     * @param qmBillConfig
     * @throws ApiException
     * @throws JsonProcessingException
     * @throws ParseException
     */
    public void getWdtSaleBillAllNumber(QMBillConfig qmBillConfig) throws ApiException, JsonProcessingException, ParseException {
        StringBuffer errorMessage =new StringBuffer();
        String qmConfig = sysConfigService.selectConfigByKey("QM_config");
        JSONObject qmConfigJson = JSON.parseObject(qmConfig);
        String qmServerUrl = (String) qmConfigJson.get("QM_serverUrl");
        String qmAppKey = (String) qmConfigJson.get("QM_appKey");
        String qmAppSecret = (String) qmConfigJson.get("QM_appSecret");
        String qmTargetAppKey = (String) qmConfigJson.get("QM_targetAppKey");
        String qmSId = (String) qmConfigJson.get("QM_sId");
        DefaultQimenCloudClient client = new DefaultQimenCloudClient(qmServerUrl, qmAppKey, qmAppSecret);
        WdtStockoutCollectQueryRequest req = new WdtStockoutCollectQueryRequest();
        req.setTargetAppKey(qmTargetAppKey);
        req.setSid(qmSId);
        if (StringUtils.isNotBlank(qmBillConfig.getShopNo())) {
            req.setShopNo(qmBillConfig.getShopNo());
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        req.setStartTime(qmBillConfig.getStartTime().format(dateTimeFormatter));
        req.setEndTime(qmBillConfig.getEndTime().format(dateTimeFormatter));
        req.setPageNo(String.valueOf(qmBillConfig.getPageNo()));
        req.setPageSize(String.valueOf(qmBillConfig.getPageSize()));
        req.setIsPq("0");
        WdtStockoutCollectQueryResponse response = client.execute(req);
        if ("".equals(response.getErrorCode())){
            int totalCount = Integer.parseInt(response.getTotalCount());
            //100是一页的最大数量
            int b = 100;
            int i = totalCount / b + (totalCount % b == 0 ? 0 : 1);
            for (int j = 0; j < i; j++) {
                qmBillConfig.setPageNo(j+1);
                getWdtSaleIssueBillTask.getWdtSaleBill(qmBillConfig);
            }
        } else {
            throw new RuntimeException(response.getMessage());
        }
    }

        @Transactional(rollbackFor = Exception.class)
    public void getWdtSaleBill(QMBillConfig qmBillConfig) throws ApiException, JsonProcessingException, ParseException {
        StringBuffer errorMessage =new StringBuffer();
        String qmConfig = sysConfigService.selectConfigByKey("QM_config");
        JSONObject qmConfigJson = JSON.parseObject(qmConfig);
        String qmServerUrl = (String) qmConfigJson.get("QM_serverUrl");
        String qmAppKey = (String) qmConfigJson.get("QM_appKey");
        String qmAppSecret = (String) qmConfigJson.get("QM_appSecret");
        String qmTargetAppKey = (String) qmConfigJson.get("QM_targetAppKey");
        String qmSId = (String) qmConfigJson.get("QM_sId");
        DefaultQimenCloudClient client = new DefaultQimenCloudClient(qmServerUrl, qmAppKey, qmAppSecret);
        WdtStockoutCollectQueryRequest req = new WdtStockoutCollectQueryRequest();
        req.setTargetAppKey(qmTargetAppKey);
        req.setSid(qmSId);
        if (StringUtils.isNotBlank(qmBillConfig.getShopNo())) {
            req.setShopNo(qmBillConfig.getShopNo());
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        req.setStartTime(qmBillConfig.getStartTime().format(dateTimeFormatter));
        req.setEndTime(qmBillConfig.getEndTime().format(dateTimeFormatter));
        req.setPageNo(String.valueOf(qmBillConfig.getPageNo()));
        req.setPageSize(String.valueOf(qmBillConfig.getPageSize()));
        req.setIsPq("0");
        WdtStockoutCollectQueryResponse response = client.execute(req);
        if ("".equals(response.getErrorCode())){
            JsonNode body = objectMapper.readTree(response.getBody());
            JsonNode res = body.get("response");
            if (res != null && "".equals(res.get("message").asText())){
                JsonNode orderList = res.get("order_list");
                for (int i = 0; i < orderList.size(); i++) {
                    JsonNode node = orderList.get(i);
                    OmsReceiptbill omsReceiptbill = new OmsReceiptbill();
                    String code = node.get("main_order_no").asText();
                    String receiptDate = node.get("consign_time").asText();
                    String invoiceCode = node.get("sales_system").asText();
                    String customerCode = node.get("shop_no").asText();
                    String costCenterCode = node.get("website").asText();
                    String isPq = node.get("is_pq").asText();
                    String totalAmount = node.get("total_amount").asText();
                    //销售收货单号
                    omsReceiptbill.setCode(code);
                    //来源系统
                    omsReceiptbill.setSrcsys("wdt");
                    //校验系统中是否存在重复数据
                    List<OmsReceiptbill> omsReceiptbills = receiptbillService.selectOmsReceiptbillList(omsReceiptbill);
                    if (StringUtils.isNotEmpty(omsReceiptbills)){
                        throw new RuntimeException("系统中存在重复的销售出库单：" + code);
                    }
                    //发货单号
                    omsReceiptbill.setShipmentcode(code);
//                    //客户编码
//                    BdCustomer bdCustomer = new BdCustomer();
//                    bdCustomer.setCustomernumber(customerCode);
//                    List<BdCustomer> bdCustomers = customerService.selectBdCustomerList(bdCustomer);
//                    if (StringUtils.isEmpty(bdCustomers)){
//                        errorMessage.append("[没有找到客户：" + customerCode + "]");
//                        throw new RuntimeException(errorMessage.toString());
//                    }
//                    bdCustomer = bdCustomers.get(0);
                    omsReceiptbill.setCustomercode(customerCode);
//                    omsReceiptbill.setCustomername(bdCustomer.getCustomername());
                    //销售组织编码
                    OmsOrgunit omsOrgunit = new OmsOrgunit();
                    omsOrgunit.setOrgnumber(invoiceCode);
                    List<OmsOrgunit> omsOrgunits = orgunitService.selectOmsOrgunitList(omsOrgunit);
                    if (StringUtils.isEmpty(omsOrgunits)){
                        errorMessage.append("[没有找到组织：" + invoiceCode + "]");
                        throw new RuntimeException(errorMessage.toString());
                    }
                    omsOrgunit = omsOrgunits.get(0);
                    omsReceiptbill.setInvoicecode(invoiceCode);
                    omsReceiptbill.setInvoicename(omsOrgunit.getOrgname());
                    //成本中心编码
                    omsReceiptbill.setCostcentercode(costCenterCode);

                    //根据销售组织和客户编码还原店铺对象
                    BdShop bdShop = new BdShop();
                    bdShop.setShopnumber(customerCode);
                    bdShop.setInvoicecode(invoiceCode);
                    List<BdShop> bdShops = shopService.selectBdShopList(bdShop);
                    if (StringUtils.isEmpty(bdShops)){
                        errorMessage.append("[根据店铺编码："+ customerCode +"和销售组织编码："+ invoiceCode +"没有找到店铺数据]");
                        throw new RuntimeException(errorMessage.toString());
                    }
                    bdShop = bdShops.get(0);
                    //销售组织仓库
                    String salewhcode = bdShop.getSalewhcode();
                    String salewhname = bdShop.getSalewhname();
                    omsReceiptbill.setSaleswarehousecode(salewhcode);
                    omsReceiptbill.setSaleswarehousename(salewhname);

                    //发货仓库
                    String facilitycode = bdShop.getFacilitycode();
                    String facilityname = bdShop.getFacilityname();
                    omsReceiptbill.setFacilitycode(facilitycode);
                    omsReceiptbill.setFacilityname(facilityname);

                    //库存组织编码
                    //库存组织数据获取店铺中获取的发货仓的库存组织
                    BdWarehouse bdWarehouse = new BdWarehouse();
                    bdWarehouse.setWarehousenumber(facilitycode);
                    List<BdWarehouse> bdWarehouses = warehouseService.selectBdWarehouseList(bdWarehouse);
                    if (StringUtils.isEmpty(bdWarehouses)){
                        errorMessage.append("[没有找到店铺：" + customerCode + "的发货仓库：" + facilitycode + "]");
                        throw new RuntimeException(errorMessage.toString());
                    }
                    bdWarehouse = bdWarehouses.get(0);
                    String storageorgnumber = bdWarehouse.getStorageorgnumber();
                    omsReceiptbill.setInventoryorganizationcode(storageorgnumber);
                    omsReceiptbill.setInventoryorganizationname(bdWarehouse.getStorageorgname());

                    //收货仓库

                    //收货日期
                    omsReceiptbill.setReceiptdate(new SimpleDateFormat("yyyy-MM-dd").parse(receiptDate));
                    //币别
                    omsReceiptbill.setCurrency("CNY");
                    //汇率
                    omsReceiptbill.setExchangerate(new BigDecimal(1));
                    //创建时间
                    omsReceiptbill.setCreatetime(new Date());
                    //是否生成下游单据
                    omsReceiptbill.setIscreatebill(0L);

                    ArrayList<OmsReceiptbillentry> omsReceiptbillentries = new ArrayList<>();
                    JsonNode detailsList = node.get("details_list");
                    for (int j = 0; j < detailsList.size(); j++) {
                        OmsReceiptbillentry omsReceiptbillentry = new OmsReceiptbillentry();
                        /**
                         * 商品的特殊处理
                         * if ("0170010002".equals(wdtStockoutCollectQueryEntry.getGoods_no())) {
                         *      wdtStockoutCollectQueryEntry.setGoods_no("99.90.301");
                         *     }
                         *     if ("05.11.04.0015".equals(wdtStockoutCollectQueryEntry.getGoods_no())) {
                         *      continue;
                         *     }
                         */
                        JsonNode billDetail = detailsList.get(j);
                        //商品编号
                        String skuCode = billDetail.get("goods_no").asText();
                        if ("0170010002".equals(skuCode)){
                            skuCode = "99.90.301";
                        }
                        String qty = billDetail.get("goods_count").asText();
                        //share_amount是含税金额。减去税额，计算不含税金额
                        String amount = billDetail.get("share_amount").asText();
                        String price = billDetail.get("share_price").asText();
                        String specNo = billDetail.get("spec_no").asText();
                        String tax = billDetail.get("tax").asText();
                        String taxRate = billDetail.get("tax_rate").asText();
                        String refOrderCode = billDetail.get("collect_no").asText();
                        String isGift = billDetail.get("gift_type").asText();
                        //商品编号
                        omsReceiptbillentry.setSkucode(skuCode);
                        //订单数量
                        omsReceiptbillentry.setQty(new BigDecimal(qty));
                        //实收数量
                        omsReceiptbillentry.setReceivedqty(new BigDecimal(qty));
                        //基本订货数量
                        omsReceiptbillentry.setBaseqty(new BigDecimal(qty));
                        //基本实收数量
                        omsReceiptbillentry.setBasereceivedqty(new BigDecimal(qty));
                        //根据物料编码还原对象
                        BdMaterial bdMaterial = new BdMaterial();
                        bdMaterial.setMaterialnumber(skuCode);
                        List<BdMaterial> bdMaterials = materialService.selectBdMaterialList(bdMaterial);
                        if (StringUtils.isEmpty(bdMaterials)){
                            errorMessage.append("[没有找到物料：" + skuCode +"]");
                            throw new RuntimeException(errorMessage.toString());
                        }
                        bdMaterial = bdMaterials.get(0);
                        //计量单位
                        String baseunitnumber = bdMaterial.getBaseunitnumber();
                        omsReceiptbillentry.setUnit(baseunitnumber);
                        omsReceiptbillentry.setBaseunit(baseunitnumber);

                        //获取税率
                        BigDecimal taxrate = bdMaterial.getTaxrate();
                        //格式化税率，用户后续计算
                        BigDecimal tempTaxrate = OmsTaskUtil.formatTaxRate(taxrate);
                        //不含税单价
                        BigDecimal noTaxPrice = new BigDecimal(price).divide(new BigDecimal(1).add(tempTaxrate), 6, BigDecimal.ROUND_HALF_UP);
                        omsReceiptbillentry.setNotaxprice(noTaxPrice);
                        //不含税总金额
                        omsReceiptbillentry.setNotaxamount(noTaxPrice.multiply(new BigDecimal(qty)));
                        //含税单价
                        omsReceiptbillentry.setTaxprice(new BigDecimal(price));
                        //含税总金额
                        omsReceiptbillentry.setTaxamount(new BigDecimal(amount));
                        //税率
                        omsReceiptbillentry.setTaxrate(taxrate);
                        //税额
                        omsReceiptbillentry.setTax(omsReceiptbillentry.getTaxamount().subtract(omsReceiptbillentry.getNotaxamount()));
                        //是否赠品
                        omsReceiptbillentry.setIsgift(Long.valueOf(isGift));
                        //collect_no放到备注字段上
                        omsReceiptbillentry.setRemark(refOrderCode);
                        omsReceiptbillentries.add(omsReceiptbillentry);
                    }
                    omsReceiptbill.setOmsReceiptbillentryList(omsReceiptbillentries);
                    receiptbillService.insertOmsReceiptbill(omsReceiptbill);
                }
            }else {
                throw new RuntimeException(String.valueOf(res.get("message")));
            }

        }else {
            throw new RuntimeException(response.getMessage());
        }
    }
}
